package com.ccys.cms.controller.consultation;


import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSONObject;
import com.ccys.cms.service.consultation.BookingPaymentPhotoService;
import com.ccys.cms.service.consultation.BookingPrescriptionService;
import com.ccys.cms.service.consultation.TblBookingPaymentService;
import com.ccys.common.util.HtmlUtils;
import com.ccys.common.vo.ResponseResult;
import com.ccys.db.entity.*;
import com.ccys.db.enums.PrescriptionFrequencyEnum;
import com.ccys.db.mapper.*;
import com.ccys.db.vo.consultation.*;
import com.google.common.collect.Maps;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
import tk.mybatis.mapper.entity.Example;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;

import static com.ccys.db.cache.TranslationUtil.getContentLastLanguage;

@RestController
@Api(tags = "问诊订单列表详情fee")
@RequestMapping("consultation")
@Slf4j
public class ConsultationDetailFeeController {


    @Resource
    private TblBookingConsultationMapper consultationMapper;


    @Resource
    private TblBookingConsultNoteMapper consultNoteMapper;


    @Resource
    private TblBookingPaymentPhotoMapper cybersourcePhotoMapper;


    @Resource
    private BookingPaymentPhotoService cyberSourcePhotoService;


    @Resource
    private TblBookingPaymentService cyberSourceService;


    @Resource
    private TblBookingOrderPhotoMapper prescriptionPhotoMapper;


    @Resource
    private TblBookingOrderMapper tblBookingOrderMapper;


    @Resource
    private BookingPrescriptionService prescriptionService;


    @ApiOperation("查询Consultation detail")
    @GetMapping("getConsultationDetail")
    public ResponseResult<TblBookingConsultation, Object> getConsultationDetail(String bookingId) {

        Example example = new Example(TblBookingConsultation.class);
        example.createCriteria().andEqualTo("bookingId", bookingId).andEqualTo("delFlag", 0);
        TblBookingConsultation res = consultationMapper.selectOneByExample(example);
        return ResponseResult.success(res);

    }


    @ApiOperation("查询CDMP")
    @GetMapping("getCdmp")
    public ResponseResult<List<ConsultationDetailCdmpVo>, Object> getCdmp(String bookingId) {


        return ResponseResult.success(consultNoteMapper.getCdmp(bookingId));
    }


    @ApiOperation("查询Medical Service Detail")
    @GetMapping("getMedicalServiceDetail")
    public ResponseResult<List<ConsultationDetailMedicalServiceDetailVo>, Object> getMedicalServiceDetail(String bookingId) {


        return ResponseResult.success(consultNoteMapper.getMedicalServiceDetail(bookingId));
    }


    @ApiOperation("查询Payment information列表")
    @GetMapping("getPaymentInfo")
    public ResponseResult<List<ConsultationDetailPaymentInfoVo>, Object> getPaymentInfo(String bookingId) {

        List<ConsultationDetailPaymentInfoVo> paymentInfoList = consultNoteMapper.getPaymentInfoList(bookingId);
        return ResponseResult.success(paymentInfoList);
    }


    @ApiOperation("添加 Payment information ")
    @PostMapping("savePaymentInfo")
    @Transactional
    public ResponseResult savePaymentInfo(TblBookingPayment model) {

        int i = cyberSourceService.insertOrUpdate(model);
        cyberSourcePhotoService.insertBatch(model);
        return ResponseResult.update(i);
    }


    @ApiOperation("修改 Payment information")
    @PostMapping("updatePaymentInfo")
    @Transactional
    public ResponseResult updatePaymentInfo(TblBookingPayment model) {

        int i = cyberSourceService.insertOrUpdate(model);
        //删除之前的photo
        cybersourcePhotoMapper.deletePhotoByCybersourceId(model.getId());
        cyberSourcePhotoService.insertBatch(model);
        return ResponseResult.update(i);
    }


    @ApiOperation("根据id查询Payment information")
    @GetMapping("getPaymentInfoById")
    public ResponseResult<TblBookingPayment, Object> getPaymentInfoById(String id) {

        TblBookingPayment entityById = cyberSourceService.findEntityById(id);
        if (ObjectUtil.isNotEmpty(entityById)) {
            List<TblBookingPaymentPhoto> photoList = cyberSourcePhotoService.findListByLimit(TblBookingPaymentPhoto.class, new ArrayList<String>() {
                {
                    add("del_flag = 0");
                    add("cybersource_id = '" + id + "'");
                }
            }, "created_on_utc desc");
            entityById.setPhotoList(photoList);
        }
        return ResponseResult.success(entityById);
    }


    @ApiOperation("查询fee detail")
    @GetMapping("getFeeDetail")
    public ResponseResult<ConsultationDetailFeeDetailVo, Object> getFeeDetail(String bookingId) {

        return ResponseResult.success(consultNoteMapper.getFeeDetail(bookingId));
    }


    @ApiOperation("查询Reactivated purchase")
    @GetMapping("getReactivatedPurchase")
    public ResponseResult<ConsultationDetailReactivatedPurchaseVo, Object> getReactivatedPurchase(String bookingId) {
        //2024/1/2 0002 Total通过前端自己计算
        //custom label(下方payment information添加的记录,如果添加多条展示多个): ---->通过getPaymentInfo接口查询
        return ResponseResult.success(consultNoteMapper.getReactivatedPurchase(bookingId));
    }


    @ApiOperation("查询fulfill列表")
    @GetMapping("getFulfillList")
    public ResponseResult<List<ConsultationDetailFulfillVo>, Object> getFulfillList(String bookingId) {

        return ResponseResult.success(consultNoteMapper.getPrescriptionFulfillList(bookingId));
    }


    @ApiOperation("查询prescription detail")
    @GetMapping("getPrescriptionDetail")
    public ResponseResult<List<ConsultationDetailPrescriptionDetailVo>, Object> getPrescriptionDetail(String bookingId) {


        /**
         *         1、有开药的情况才展示此版块
         *         2、只有 packed medication 上传了照片(读取电脑摄像头)才可以“notify checker”。
         *         3、verify medications 只可以一次
         *         4、使用 benefit 时，有不包含的药才展示红色叹号提示
         *         5、复购的药，在名称后添加(reactivated)
         *         6、按照药房名称排序
         *         7、印尼病人开药才展示send pre…，调用 GAP 接口通知
         */

        return ResponseResult.success(consultNoteMapper.getPrescriptionDetail(bookingId));
    }


    @ApiOperation("添加prescription照片")
    @PostMapping("savePrescriptionPhoto")
    @Transactional
    public ResponseResult savePrescriptionPhoto(TblBookingOrderPhoto model) {

        // TODO: 2024/1/3 0003 能否批量添加
        return ResponseResult.update(prescriptionPhotoMapper.insert(model));
    }


    @ApiOperation("verify prescription")
    @PutMapping("verifyPrescription")
    @Transactional
    public ResponseResult verifyPrescription(String id, Integer verify) {
        Example example = new Example(TblBookingOrder.class);
        example.createCriteria().andEqualTo("prescriptionId",id).andEqualTo("delFlag",0);
        TblBookingOrder tblBookingOrder = new TblBookingOrder();
        tblBookingOrder.setVerified(verify);
        return ResponseResult.update(tblBookingOrderMapper.updateByExampleSelective(tblBookingOrder,example));

//        TblBookingPrescription model = new TblBookingPrescription();
//        model.setId(id);
//        model.setVerified(verify);
//        int i = prescriptionService.insertOrUpdate(model);
//        return ResponseResult.update(i);

    }


    // TODO: 2024/1/3 0003 prescription的notify checker
    // TODO: 2024/1/3 0003  send to 印尼病人

    @ApiOperation("查询aia corporate信息")
    @GetMapping("getAIACorporateInfo")
    public ResponseResult<ConsultationDetailAIAVo, Object> getAIACorporateInfo(String bookingId) {

        return ResponseResult.success(consultNoteMapper.getAIACorporateInfo(bookingId));
    }

    // TODO: 2024/1/6 0006 下载pdf的时间转换放到代码中
    // TODO: 2024/1/6 0006 visible 字段的确认
    // TODO: 2024/1/6 0006 不明确的字段
    // TODO: 2024/1/6 0006 数据脱敏
    @ApiOperation("下载 Prescription pdf 文件")
    @GetMapping("/downloadPDF/prescriptionDetail")
    public ResponseResult downloadPrescriptionDetail(HttpServletResponse response, String bookingId) {
        try {
            PrescriptionPDFVo data = consultNoteMapper.getPrescriptionPdfData(bookingId);
            // 组装服药的frequency信息
            /**
             * {tbl_product.rp_id关联tbl_formulation_route_patient} +
             * {tbl_booking_prescription.uom_quantity} +
             * {frequency的描述} + {tbl_booking_prescription.duration} +
             * {tbl_booking_prescription.duration_unit}(s)
             */
            List<MedicationListPDFVo> medicationsList = data.getMedicationsList();
            if (CollectionUtils.isNotEmpty(medicationsList)) {
                // 1、组装fullfill信息
                // 服药信息下面的信息 是 takeCompleteCourse + anyPrecautions + whatIsFor
                // 组装状态按钮的信息 如果 fullfill != quantity 则显示 红色按钮 “Not Fullfilled” ,
                // 相等显示绿色按钮 “Purchased”
                medicationsList.forEach(x -> {
                    //fullfilled
                    Integer quantity = x.getQuantity();
                    Integer quantityFulfilled = x.getQuantityFulfilled();
                    String fullfillDescription = "(Quantity fullfilled:" + quantityFulfilled + "/" + quantity + ")";
                    x.setFulfillDescription(fullfillDescription);
                    //frequency
                    String frequency = x.getFrequency();
//                    "1day 2week 3month 4year"
                    String durationUnitStr = "day";
                    switch (x.getDurationUnit()) {
                        case 2:
                            durationUnitStr = "week";
                            break;
                        case 3:
                            durationUnitStr = "month";
                            break;
                        case 4:
                            durationUnitStr = "year";
                            break;
                        default:
                            durationUnitStr = "day";
                    }
                    String frequencyValue = PrescriptionFrequencyEnum.valueOf(frequency).getValue();
                    String frequencyDescription = x.getActionName() + " " + x.getUomQuantity() + " "
                            + frequencyValue + " " + x.getDuration() + " " + durationUnitStr + "(s)";
                    x.setFrequencyDescription(frequencyDescription);

                    //status
                    //purchased(status = 2 or quantityFullfilled = quantity),
                    // Partiallu Fulfilled(quantity > quantityFullfilled > 0 橘色)
                    // Not fulfilled(status = 0 and quantityFullfilled=0)
                    //颜色 chartreuse
                    //     orange
                    //     orangered
                    if (quantity != null && quantity.equals(quantityFulfilled)) {
                        x.setStatusLabel("Purchased");
                        x.setStatusColor("chartreuse");
                    } else if (quantity != null && quantityFulfilled != null && quantity > quantityFulfilled) {
                        x.setStatusLabel("Partially Fulfilled");
                        x.setStatusColor("orange");
                    } else {
                        x.setStatusLabel("Not fulfilled");
                        x.setStatusColor("orangered");
                    }

                });


            }
            // new SimpleDateFormat("dd MMM yy"); 转时间
            SimpleDateFormat sdf = new SimpleDateFormat("dd MMM yy");
            String visitDateStr = sdf.format(data.getVisitDate());
            data.setVisitDateStr(visitDateStr);

            Date consultationEndDate = data.getConsultationEndDate();
            if (consultationEndDate != null) {
                String conStr = sdf.format(consultationEndDate);
                data.setConsultationEndDateStr(conStr);
            }

            //国际化
            data.setNameText(getContentLastLanguage("NAME",data.getLastLanguage()));
            data.setIdNoText(getContentLastLanguage("ID_NO",data.getLastLanguage()));
            data.setMCRNoText(getContentLastLanguage("MCR_NO",data.getLastLanguage()));
            data.setPartnershipWithText(getContentLastLanguage("IN_PARTNERSHIP_WITH",data.getLastLanguage()));
            data.setVisitDateText(getContentLastLanguage("VISITDATE",data.getLastLanguage()));
            data.setPrescriptionText(getContentLastLanguage("PRESCRIPTION",data.getLastLanguage()));
            data.setAgeText(getContentLastLanguage("AGE",data.getLastLanguage()));
            data.setConsultationNoText(getContentLastLanguage("CONSULTATION_NO",data.getLastLanguage()));
            data.setWhiteCoatPrescriptionText(getContentLastLanguage("WHITECOAT_PRESCRIPTION",data.getLastLanguage()));
            //address_text只针对马来西亚使用
            if("136".equals(data.getPatientCountry())){
                data.setVisibleAddress("block");
                data.setAddress(data.getDetailAddress());
            }
            //footNote只展示在越南
            if("21".equals(data.getPatientCountry())){
                data.setFootNote(getContentLastLanguage("FOOTNOTE",data.getLastLanguage()));
            }

            HashMap<String, Object> mapData = Maps.newHashMap();
            mapData.put("data", data);
            long timeMillis = System.currentTimeMillis();
            String templateContent = HtmlUtils.getTemplateContent("PrescriptionPDF.ftl", mapData);
            HtmlUtils.html2Pdf(response, templateContent, timeMillis + "");
        } catch (Exception e) {
            log.error("error occurs when downloading file,{}", e);

        }
        return ResponseResult.success("ok");
    }


    @ApiOperation("下载 original receipt pdf 文件")
    @GetMapping("/downloadPDF/originalReceipt")
    public ResponseResult downloadOriginalReceipt(HttpServletResponse response, String bookingId) {
        try {

            // TODO: 2024/1/10 0010 waive 掉之后费用怎么显示。。。。

            OriginReceiptPDFVo data = consultNoteMapper.getOriginalReceiptPdfData(bookingId);
            // 2024/1/6 0006 税 计算 bigdecimal * 100 + “%”
            String gstText = data.getGSTText();
            BigDecimal taxRate = data.getTaxRate();
            if (taxRate != null) {
                BigDecimal taxRateV2 = taxRate.multiply(new BigDecimal(100));
                gstText = "GST(" + taxRateV2 + "%)";
            } else {
                taxRate = new BigDecimal(0);
                gstText = "GST";
            }
            data.setGSTText(gstText);
            // 2024/1/6 0006 税费 = standard * GST （GST_type 为 0 ）
            BigDecimal totalValueExclGst = data.getTotalValueExclGst();
            if (totalValueExclGst != null) {
                BigDecimal GST = totalValueExclGst.multiply(taxRate);
                data.setGST(GST);
            }
            //medicationsList是否可见
            boolean notEmpty = CollectionUtils.isNotEmpty(data.getMedicationsFeeList());
            data.setVisibleMedicationFee(notEmpty ? "block" : "none");

            //promotionFee
            String promoCode = data.getPromoCode();
            JSONObject promoJSON = JSONObject.parseObject(promoCode);
//            {
//                "id": 523,
//                    "name": "yscode",
//                    "patient_identifier": "yscode title",
//                    "reusable": true,
//                    "limit_number": 0,
//                    "used_number": 1,
//                    "type": 3,
//                    "amount": 24.0,
//                    "start_date": "2023-11-26T00:00:00",
//                    "end_date": "2025-01-09T15:30:49.997",
//                    "is_active": true,
//                    "version": 1,
//                    "patient_identifier_value": "($1.60)",
//                    "is_applies": true,
//                    "is_apply_promo_after_tax": false
//            }
            if (Objects.nonNull(promoJSON)) {
                data.setPromoName(promoJSON.getString("name"));
                data.setPromoFee(promoJSON.getString("patient_identifier_value"));
            }

            //cdmp fee
            List<CDMPFeePDFVo> cdmpFeeList = data.getCDMPFeeList();
            if (CollectionUtils.isNotEmpty(cdmpFeeList)) {
                data.setVisibleCDMPFee("block");
                //benefitname
                data.setCDMPBenefitName(cdmpFeeList.get(0).getBenefitName());
            } else {
                data.setVisibleCDMPFee("none");
            }

            //medical service fee
            List<MedicalServiceFeePDFVo> medicalServiceFeeList = data.getMedicalServiceFeeList();
            if (CollectionUtils.isNotEmpty(medicalServiceFeeList)) {
                data.setVisibleMedicalService("block");
                //计算金额
                Double medicalServiceFee = data.getMedicalServiceFee();
                Double serviceTypeFee = data.getServiceTypeFee();
                Double packageMedicalServiceFee = data.getPackageMedicalServiceFee();
                data.setMedicalServiceSubtotalValue(medicalServiceFee + serviceTypeFee + packageMedicalServiceFee);

            } else {
                data.setVisibleMedicalService("none");
            }


            //  保险
            // 3、使用benefit时，展示tbl_booking_fee中benefits,co_pay,excess对应的金额，
            // 如果为0或空则不展示。
            // benefits展示对应Corporate benefit(使用的DC,10384133526394)、
            // AIA Corporate Benefit(使用的AIA,51275896042676)、
            // WhiteCoat TeleHealth Family Plan ‑ Singtel (使用SUB时展示的是SUB的名称,56423610401837)、
            // Plan Benefit(使用CDMP时94427946053522)、
            // AIA Mum2Baby Benefit (使用AIA healthshield时展示的时benefit的名称，20029359736607)。
            // co_pay展示Co‑Payment Payable。
            // excess展示Outstanding Amount Payable。
            //问诊使用的配套类型0:retail 1:AIA corporate;2:Direct corporate;3:AIA Healthshield;4:Subscription;5:EAP;6:CDMP
            if (ObjectUtil.isNotNull(data.getBenefits()) && data.getBenefits() != 0) {
                data.setVisibleAIA("block");
                Integer planType = data.getPlanType();
                if (ObjectUtil.isNotNull(planType)) {
                    switch (planType) {
                        case 1:
                            data.setBenefitName("AIA Corporate Benefit");
                            break;
                        case 2:
                            data.setBenefitName("Corporate benefit");
                            break;
                        case 6:
                            data.setBenefitName("Plan Benefit");
                            break;
                        default:
                            break;
                    }
                }
            } else {
                data.setVisibleAIA("none");
            }


            //  2024/1/8 0008  转时间
            // new SimpleDateFormat("dd MMM yy"); 转时间
            SimpleDateFormat sdf = new SimpleDateFormat("dd MMM yy");
            data.setReceiptDateStr(sdf.format(data.getReceiptDate()));
            data.setVisitDateStr(sdf.format(data.getVisitDate()));
            //导出pdf

            HashMap<String, Object> mapData = Maps.newHashMap();
            //国际化
            data.setNameText(getContentLastLanguage("NAME",data.getLastLanguage()));
            data.setIdNoText(getContentLastLanguage("ID_NO",data.getLastLanguage()));
            data.setPartnershipWithText(getContentLastLanguage("IN_PARTNERSHIP_WITH",data.getLastLanguage()));
            data.setVisitDateText(getContentLastLanguage("VISITDATE",data.getLastLanguage()));
            data.setTotalInclGSTText(getContentLastLanguage("TOTAL_INCL_GST",data.getLastLanguage()));
            data.setMedicalServiceSubtotalText(getContentLastLanguage("SUB_TOTAL",data.getLastLanguage()));
            data.setClinicLicenceNoText(getContentLastLanguage("CLINIC_LICENSE_NO",data.getLastLanguage()));
            data.setConsultationSubTotalText(getContentLastLanguage("SUB_TOTAL",data.getLastLanguage()));
            //todo 没找到翻译
//            data.setCopayText(getContentLastLanguage("",data.getLastLanguage()));
            data.setDiagnosisText(getContentLastLanguage("DIAGNOSIS",data.getLastLanguage()));
            data.setGSTText(Objects.nonNull(data.getTaxRate())?data.getTaxRate().toString():"GST");
            data.setExcessText(getContentLastLanguage("OUTSTANDING_AMOUNT_PAID",data.getLastLanguage()));
            data.setDeliveryChargeText(getContentLastLanguage("DELIVERY_CHARGE",data.getLastLanguage()));
            //todo 没找到翻译
//            data.setPracticeChargeText(getContentLastLanguage("",data.getLastLanguage()));
            data.setTotalExclGSTText(getContentLastLanguage("TOTAL_EXCL_GST",data.getLastLanguage()));
            data.setMedicationSubtotalText(getContentLastLanguage("SUB_TOTAL",data.getLastLanguage()));
            //todo 没找到翻译
//            data.setMedicalServiceText(getContentLastLanguage("",data.getLastLanguage()));
            if(data.getShowNoteUniqueTransactionCode()==1){
                data.setNoteUniqueTransactionCode(getContentLastLanguage("NOTE_UNIQUE_TRANSACTION_CODE",data.getLastLanguage()));
            }
            //越南展示supportVNemailContent
            if("21".equals(data.getPatientCountry())){
                data.setSupportVNEmailContent(getContentLastLanguage("Support_VN_Email_Content",data.getLastLanguage()));
                data.setSupportVNEmail("block");
            }

            //脱敏
            String idNo = data.getIdNo();
            try {
                StringBuilder sb = new StringBuilder(idNo);
                for(int i=1;i<sb.length()-4;i++){
                    sb.setCharAt(i,'*');
                }
                data.setIdNo(sb.toString());
            }catch (Exception e){

            }

            mapData.put("data", data);
            long timeMillis = System.currentTimeMillis();
            String templateContent = HtmlUtils.getTemplateContent("ReceiptPDF.ftl", mapData);
            HtmlUtils.html2Pdf(response, templateContent, timeMillis + "");

        } catch (Exception e) {
            log.error("error occurs when downloading file,{}", e);

        }
        return ResponseResult.success();
    }
}
